package GUI;

import java.awt.Button;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.management.MemoryUsage;
import java.net.Inet4Address;
import java.net.UnknownHostException;
import java.util.ArrayList;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

import client.OBL_Client;

import server.OBL_Server;
import java.awt.GridLayout;
import java.awt.BorderLayout;

import logic.Member;
import logic.Message;
import logic.SystemMesseges;

import javax.swing.JButton;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import javax.swing.UIManager;

public class Client_GUI extends JFrame {
	
	//Class variables
	public static int MENU_WIDTH = 150;
	public static int MENU_HEIGHT = 514;
	public static int MAIN_WIDTH = 808;
	public static int MAIN_HEIGHT = 514;
	
	//Class accessible gui items
	private JPanel Menu_Container_Panel;
	private JPanel Main_Container_Panel;
	
	//TODO set as private with getter
	public JPanel currentMain;
	
	//TODO set as private with getter + setter
	public JLabel resultLabel;
	
	public JButton btnLogoff;

	
	
	public boolean safeToClear = true;
	
	private Client_GUI self;
		
	public OBL_Client client;
	private JLabel loadingLBL;
	public JLabel labelMeesege;
	public JLabel msgNum;
	
	public Client_GUI (){
		self = this;
		
		ImageIcon LOGOImageIcon = new ImageIcon(getClass().getClassLoader().getResource("resource/LOGO.jpg"));
		ImageIcon LOGO = new ImageIcon (LOGOImageIcon.getImage().getScaledInstance(149, 110, java.awt.Image.SCALE_SMOOTH));
		
		ImageIcon TOPPANELImageIcon = new ImageIcon(getClass().getClassLoader().getResource("resource/TOP.JPG"));
		ImageIcon TOPPANEL = new ImageIcon (TOPPANELImageIcon.getImage().getScaledInstance(808, 110, java.awt.Image.SCALE_SMOOTH));
		
		ImageIcon ENVELOPEImageIcon = new ImageIcon(getClass().getClassLoader().getResource("resource/env.jpg"));
		final ImageIcon ENVELOPE = new ImageIcon (ENVELOPEImageIcon.getImage().getScaledInstance(40, 20, java.awt.Image.SCALE_SMOOTH));
		ImageIcon ENVELOPEImageIconOn = new ImageIcon(getClass().getClassLoader().getResource("resource/envOn.jpg"));
		final ImageIcon ENVELOPEON = new ImageIcon (ENVELOPEImageIconOn.getImage().getScaledInstance(40, 20, java.awt.Image.SCALE_SMOOTH));
		
		setResizable(false);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setMinimumSize(new Dimension(960,650));
		this.setLocation(200, 80);
		getContentPane().setLayout(null);		
		
		
		ImagePanel pnl = new ImagePanel(TOPPANEL.getImage());
		
		//dfghdbxzfuyhn
		JPanel TopPenel = new JPanel();
		TopPenel.setBackground(Color.GREEN);
		TopPenel.setBounds(0, 0, 956, 108);
		getContentPane().add(TopPenel);
		TopPenel.setLayout(null);
				
		JLabel LBLLogo = new JLabel("");
		LBLLogo.setBounds(807, 0, 149, 108);
		TopPenel.add(LBLLogo);
		LBLLogo.setIcon(LOGO);
		
		JLabel lblBack = new JLabel("");
		lblBack.setBounds(44, -2, 808, 110);
		lblBack.setIcon(TOPPANEL);


		TopPenel.setOpaque(false);
		
		TopPenel.revalidate();
		JLabel lblNewLabel = new JLabel("OBL");
		lblNewLabel.setBounds(20, 11, 117, 23);
		TopPenel.add(lblNewLabel);
		lblNewLabel.setFont(new Font("Tahoma", Font.BOLD, 18));
		
		btnLogoff = new JButton("Logoff");
		btnLogoff.setBounds(10, 74, 89, 23);
		TopPenel.add(btnLogoff);
		
		loadingLBL = new JLabel("");
		loadingLBL.setBounds(350, 11, 110, 86);
		TopPenel.add(loadingLBL);
		
		resultLabel = new JLabel("");
		resultLabel.setBounds(195, 68, 149, 35);
		TopPenel.add(resultLabel);
		
		labelMeesege = new JLabel("");
		labelMeesege.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				
				SystemmessageGui messages = new SystemmessageGui(self);
				self.RepaintMain(messages);
			}
			@Override
			public void mouseEntered(MouseEvent arg0) {
				labelMeesege.setIcon(ENVELOPEON);
			}
			@Override
			public void mouseExited(MouseEvent e) {
				labelMeesege.setIcon(ENVELOPE);
			}
		});
		labelMeesege.setBounds(113, 74, 40, 23);
		TopPenel.add(labelMeesege);
		labelMeesege.setIcon(ENVELOPE);
		labelMeesege.setVisible(false);
		
		btnLogoff.setVisible(false);
		btnLogoff.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				
				if (safeToClear){ //safe to repaint the screen
					Login(client.GetUID(), "", false); //password is irrelivent for logoff
					
					setTopFrameTitle("Hello System User!");
					btnLogoff.setVisible(false);
					labelMeesege.setVisible(false);
					resultLabel.setVisible(false);
					msgNum.setVisible(false);
					client.Privelege = Member.SYSTEM_USER_PRIVILIGE;
					
					client.publicMessages = null;
					client.privateMessages = null;
					
					setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
					
//					try {client.closeConnection();} 
//					catch(IOException exc){
//						//TODO handle error
//					}
					//setHostIP("localhost");
					
					LoginSystemUser();
					RepaintMenu(0);
					
				}else{ //user is in the middle of a page
					JPanel torepaint = null;
					VerifyDialog verify = new VerifyDialog(self, torepaint, true);
				}

			}
		});
		lblNewLabel.setVisible(true);
		
		Menu_Container_Panel = new JPanel();
		Menu_Container_Panel.setBackground(Color.WHITE);
		Menu_Container_Panel.setBounds(808, 109, MENU_WIDTH, MENU_HEIGHT);
		getContentPane().add(Menu_Container_Panel);
		Menu_Container_Panel.setLayout(null);
		
		Main_Container_Panel = new JPanel();
		Main_Container_Panel.setBackground(UIManager.getColor("inactiveCaption"));
		Main_Container_Panel.setBounds(0, 109, MAIN_WIDTH, MAIN_HEIGHT);
		getContentPane().add(Main_Container_Panel);
		Main_Container_Panel.setLayout(new BorderLayout(0, 0));
		
		msgNum = new JLabel();
		msgNum.setBounds(160, 78, 40, 14);
		TopPenel.add(msgNum);
		
		this.pack();
		this.setVisible(true);
		
		TopPenel.add(pnl);
						
		LoadIpFromFile();
		//setHostIP("localhost");
		LoginSystemUser();
	}
	
	/**
	 * This function loads the configuraion file for the SERVER IP
	 */
	private void LoadIpFromFile(){
		  try {
			  BufferedReader br = new BufferedReader(new FileReader(new File("conf.txt")));
		      String temp = br.readLine();
		      temp = br.readLine();
		      String IP = temp.substring(temp.indexOf("=")+1,temp.length());
		      
		      setHostIP(IP);
		  }catch (IOException e) {e.printStackTrace();}
	}
	
	
	/**
	 * This function receives an ArrayList<SystemMessages> and sets the number
	 * of unread messages near the envelope
	 * @param messages - ArrayList<SystemMessages> containing the SystemMessages
	 */
	public void GetMessages(ArrayList<SystemMesseges> messages){
		int msgCounter = 0;
		for(SystemMesseges message : messages){
			if (message.getREAD() == SystemMesseges.MESSAGE_UNREAD) msgCounter++;
		}
		msgNum.setText(String.valueOf(msgCounter));
		if (msgCounter > 0) msgNum.setForeground(Color.red);
		else msgNum.setForeground(Color.black);
		msgNum.setVisible(true);
	}
	
	
	/**
	 * This function handles the loading logo
	 * True to turn on, False to turn off
	 * @param value - wheter to turn on or off the loading
	 */
	public void SetLoading(boolean value){
		if (value){
			ImageIcon loading = new ImageIcon(getClass().getClassLoader().getResource("resource/loading.gif"));
			loadingLBL.setIcon(loading);
		}else loadingLBL.setIcon(null);
	}
	
	
	/** send a login/logoff request to the server
	 *@param user - username
	 *@param pass - password
	 *@param login - boolean value for login or logoff (true = login)
	 */	
	public void Login(String user,String pass,boolean login){
		
		int action = 0;
		if (login){
			action = Message.LOGIN_REQUEST;
		}else{
			action = Message.LOGOFF_REQUEST;
		}
		
		ArrayList<String> index = new ArrayList<String>();
		index.add("username");
		index.add("password");
		ArrayList<Object> data = new ArrayList<Object>();
		data.add(user);
		data.add(pass);
		Message send = new Message(index,data,action);
		
		try {
			if(client.isConnected() == false){
				client.openConnection();
			}
			client.sendToServer(send);
			if (login) this.client.SetUID(user);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	
	
	/** send a System_User_Login request to the server
	 */	
	public void LoginSystemUser(){
		
		int action = Message.LOGIN_REQUEST;
		
		ArrayList<String> index = new ArrayList<String>();
		index.add("systemuser");
		ArrayList<Object> data = new ArrayList<Object>();

		Message send = new Message(index,data,action);
		
		try {
			client.sendToServer(send);
		} catch (IOException e) {}
		
	}
	
	/**
	 * Set the host IP of the server
	 * @param ip - the server's IP
	 */
	public void setHostIP(String ip){
		//TODO set to get host & port from external file
		
		int port = OBL_Server.DEFAULT_PORT;
		client = new OBL_Client(ip, port,this);
		
		try {
			client.openConnection();
		} catch (IOException e) {}
	}
	
	//TODO - this is a TEMP!!!! function - rehandle this!
	public void setTopFrameTitle(String res){
		resultLabel.setText(res);
	}
	
	/**
	 * This function handles the repaint of the main panel
	 * @param topaint - The JPanel to repaint as the main panel
	 * return value: 1 - repainted, 0 - not repainted
	 */
	public int RepaintMain(JPanel topaint){
		if (!safeToClear) {
			VerifyDialog verify = new VerifyDialog(this, topaint,false);
		}else{
			loadingLBL.setIcon(null);
			Main_Container_Panel.removeAll();
			Main_Container_Panel.repaint();
			Main_Container_Panel.add(topaint);
			Main_Container_Panel.revalidate();
			return 1;
		}
		return 0;
	}
	
	/**
	 * This function handles the repaint of the menu panel
	 * @param priv - the user's privilege level
	 */
	public void RepaintMenu(int priv){
		
		Home home = new Home(this,client.publicMessages);
		
		switch(priv){
		case 0:{//SystemUser
			SystemUser_Menu menu = new SystemUser_Menu(this);
			Menu_Container_Panel.removeAll();
			Menu_Container_Panel.repaint();
			Menu_Container_Panel.add(menu);
			Menu_Container_Panel.revalidate();
			
			break;
		}
		case 1:{//Manager
			Manager_Menu menu = new Manager_Menu(this);
			Menu_Container_Panel.removeAll();
			Menu_Container_Panel.repaint();
			Menu_Container_Panel.add(menu);
			Menu_Container_Panel.revalidate();
			
			break;
		}
		case 100:{//Librarian
			Librarian_Menu menu = new Librarian_Menu(this);
			Menu_Container_Panel.removeAll();
			Menu_Container_Panel.repaint();
			Menu_Container_Panel.add(menu);
			Menu_Container_Panel.revalidate();
			
			break;
		}
			
		case 1000:{//Member
			Member_menu menu = new Member_menu(this);
			Menu_Container_Panel.removeAll();
			Menu_Container_Panel.repaint();
			Menu_Container_Panel.add(menu);
			Menu_Container_Panel.revalidate();
			
			break;
		}
		
		}//end switch
		
		RepaintMain(home);
	}
	
	public int sendMessageToServer(Message toSend){
		try{
			if(!client.isConnected())
				client.openConnection();
			client.sendToServer(toSend);
		}catch(IOException e){
			return 0;
		}
		return 1;
	}
	
	/**
	 * Main function - creates the GUI
	 * @param args
	 */
	public static void main(String[] args) {
		
		Client_GUI gui = new Client_GUI();
	}
	
	
	class ImagePanel extends JPanel {

		  private Image image;

		  public ImagePanel(Image img) {
		    this.image= img;
		    Dimension size = new Dimension(image.getWidth(null), image.getHeight(null));
		    setPreferredSize(size);
		    setMinimumSize(size);
		    setMaximumSize(size);
		    setSize(size);
		    setLayout(null);
		  }

		  public void paintComponent(Graphics g) {
		    g.drawImage(image, 0, 0, null);
		  }

	}
}
